package com.baidu.disconf.client.store.inner;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baidu.disconf.client.common.model.DisconfCenterBaseModel;
import com.baidu.disconf.client.common.model.DisconfCenterFile;
import com.baidu.disconf.client.common.model.DisconfCenterItem;
import com.baidu.disconf.client.common.update.IDisconfUpdatePipeline;
import com.baidu.disconf.client.config.DisClientConfig;

/**
 * 閰嶇疆浠撳簱,鏄釜鍗曚緥
 *
 * @author liaoqiqi
 * @version 2014-6-9
 */
public class DisconfCenterStore {

    protected static final Logger LOGGER = LoggerFactory.getLogger(DisconfCenterStore.class);

    private DisconfCenterStore() {

    }
    
    
    protected static ConcurrentHashMap<ClassLoader,DisconfCenterStore> INSTANCES = new ConcurrentHashMap<>();
   
    public static boolean release(){
		synchronized (INSTANCES) {
			return INSTANCES.remove(Thread.currentThread().getContextClassLoader()) != null;
		}

	}

    public static DisconfCenterStore getInstance() {
    	synchronized (INSTANCES) {
			ClassLoader key = Thread.currentThread().getContextClassLoader();
			if(INSTANCES.containsKey(key))
				return INSTANCES.get(key);
			DisconfCenterStore value = new DisconfCenterStore();
			INSTANCES.put(key, value);
			return value;
		}
    }

    // 姣忎釜閰嶇疆鏂囦欢涓�鏉�
    // key: 閰嶇疆鏂囦欢鍚�
    // value: 閰嶇疆鏂囦欢鏁版嵁
    private Map<String, DisconfCenterFile> confFileMap = new HashMap<String, DisconfCenterFile>();

    // 姣忎釜閰嶇疆Item涓�鏉�
    // key: 閰嶇疆椤圭殑Key
    // value: 閰嶇疆椤规暟鎹�
    private Map<String, DisconfCenterItem> confItemMap = new HashMap<String, DisconfCenterItem>();

    // 涓诲鍒囨崲鏃剁殑Key鍒楄〃
    private List<String> activeBackupKeyList;

    //
    private IDisconfUpdatePipeline iDisconfUpdatePipeline = null;

    // 鏍囪瘑鏈満鍣ㄥ悕
    private String machineName;

    /**
     * 瀛樺偍 涓�涓厤缃枃浠�
     */
    public void storeOneFile(DisconfCenterBaseModel disconfCenterBaseModel) {

        DisconfCenterFile disconfCenterFile = (DisconfCenterFile) disconfCenterBaseModel;

        String fileName = disconfCenterFile.getFileName();

        if (confFileMap.containsKey(fileName)) {

            LOGGER.warn("There are two same fileName key!!!! " + fileName);
            DisconfCenterFile existCenterFile = confFileMap.get(fileName);

            // 濡傛灉鏄� 鍚屾椂浣跨敤浜� 娉ㄨВ寮� 鍜� 闈炴敞瑙ｅ紡 涓ょ鏂瑰紡锛屽垯褰撲慨鏀规椂涔熻 杩涜 XML 寮� reload
            if (disconfCenterFile.isTaggedWithNonAnnotationFile()) {
                existCenterFile.setIsTaggedWithNonAnnotationFile(true);
            }

        } else {
            confFileMap.put(fileName, disconfCenterFile);
        }
    }

    /**
     * 瀛樺偍 涓�涓厤缃」
     */
    public void storeOneItem(DisconfCenterBaseModel disconfCenterBaseModel) {

        DisconfCenterItem disconfCenterItem = (DisconfCenterItem) disconfCenterBaseModel;

        String key = disconfCenterItem.getKey();

        if (confItemMap.containsKey(key)) {

            LOGGER.error("There are two same item key!!!! " + "first: " + confItemMap.get(key).getClass().toString() +
                    ", Second: " + disconfCenterItem.getClass().toString());
        } else {
            confItemMap.put(key, disconfCenterItem);
        }
    }

    /**
     * 鍒犻櫎涓�涓厤缃」
     */
    public void excludeOneItem(String key) {

        if (confItemMap.containsKey(key)) {
            confItemMap.remove(key);
        }
    }

    /**
     * 鍒犻櫎涓�涓厤缃枃浠�
     */
    public void excludeOneFile(String key) {

        if (confFileMap.containsKey(key)) {
            confFileMap.remove(key);
        }
    }

    public Map<String, DisconfCenterFile> getConfFileMap() {
        return confFileMap;
    }

    public Map<String, DisconfCenterItem> getConfItemMap() {
        return confItemMap;
    }

    public List<String> getActiveBackupKeyList() {
        return activeBackupKeyList;
    }

    public String getMachineName() {
        return machineName;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }

    public IDisconfUpdatePipeline getiDisconfUpdatePipeline() {
        return iDisconfUpdatePipeline;
    }

    public void setiDisconfUpdatePipeline(
            IDisconfUpdatePipeline iDisconfUpdatePipeline) {
        this.iDisconfUpdatePipeline = iDisconfUpdatePipeline;
    }
}
